home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / ExtraLib / include / rhosigma / rhosigma.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-01  |  12.4 KB  |  338 lines

  1. /* ___________________________________________________________________________
  2. ** |*************************************************************************|
  3. ** |*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|
  4. ** |*| Set TAB to 4 for best readable file layout.  |*|  C++ MaxonDev 4.0  |*|
  5. ** |*|______________________________________________|*|____________________|*|
  6. ** |*************************************************************************|
  7. ** |*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|
  8. ** |*|               |*|  $Id: rhosigma.c (28.04.01)                       |*|
  9. ** |*| ###### ###### |*|  RhoSigma Source based on NDK 3.1 Includes 40.15  |*|
  10. ** |*| ##  ## ##   # |*| _________________________________________________ |*|
  11. ** |*| ##  ##  ##    |*|                                                   |*|
  12. ** |*| ######   ##   |*|  Source file with RhoSigma's support functions    |*|
  13. ** |*| ##      ##    |*|                                                   |*|
  14. ** |*| ##     ##   # |*| ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ |*|
  15. ** |*| ##     ###### |*|  Copyright © 1998-2001 RhoSigma, Roland Heyder    |*|
  16. ** |*|               |*|  All Rights Reserved.                             |*|
  17. ** |*|_______________|*|___________________________________________________|*|
  18. ** |*************************************************************************|
  19. ** ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  20. */
  21.  
  22. /* Struktur-Includes */
  23. #include <exec/types.h>
  24.  
  25. /* Library-Includes */
  26. #include <stdarg.h>
  27. #include <string.h>
  28. #include <clib/alib_protos.h>
  29. #include <pragma/exec_lib.h>
  30.  
  31. /* Source-Header */
  32. #include <rhosigma/rhosigma.h>
  33.  
  34. /*
  35. ** ---------------------------------------
  36. ** Funktionen aus RhoSigma-Include-Dateien
  37. ** ---------------------------------------
  38. */
  39.  
  40. /* deklariert in »settings.h« */
  41. VOID DAJOIN(UWORD Count, ...)
  42. {
  43.     STRPTR  TxtPtr;
  44.     WORD    *xPosPtr;
  45.     UWORD   TxtLen, SpcLen, ArgCnt;
  46.     va_list ArgPtr;
  47.  
  48.     va_start(ArgPtr, Count);
  49.     for (ArgCnt=NULL; ArgCnt<Count; ArgCnt++)
  50.     {
  51.         /* Füllbytes von NULL auf SPACE ändern */
  52.         TxtPtr = va_arg(ArgPtr, STRPTR);
  53.         TxtLen = strlen(TxtPtr+3);
  54.         SpcLen = (3-((TxtLen)&3));
  55.         strncat(TxtPtr+3,"   ",SpcLen);
  56.  
  57.         /* gewünschte Ausrichtung berechnen */
  58.         xPosPtr = (WORD*) TxtPtr;
  59.              if (xPosPtr[0] == (WORD) DATPOS_C) xPosPtr[0] = (640-(TxtLen*8))/2
  60.         else if (xPosPtr[0] == (WORD) DATPOS_L) xPosPtr[0] = 12;
  61.         else if (xPosPtr[0] == (WORD) DATPOS_R) xPosPtr[0] = (640-(TxtLen*8))-12;
  62.     }
  63. }
  64.  
  65. /* deklariert in »extradefs.h« */
  66. VOID SMTJOIN(UWORD Count, ...)
  67. {
  68.     STRPTR  TxtPtr;
  69.     WORD    *xPosPtr;
  70.     UWORD   TxtLen, SpcLen, ArgCnt;
  71.     va_list ArgPtr;
  72.  
  73.     va_start(ArgPtr, Count);
  74.     for (ArgCnt=NULL; ArgCnt<Count; ArgCnt++)
  75.     {
  76.         /* Füllbytes von NULL auf SPACE ändern */
  77.         TxtPtr = va_arg(ArgPtr, STRPTR);
  78.         if (TxtPtr[3] == (UBYTE) FALSE)
  79.         {
  80.             TxtLen = strlen(TxtPtr+4);
  81.             SpcLen = ((6-((TxtLen)&3))&3);
  82.             strncat(TxtPtr+4,"   ",SpcLen);
  83.         }
  84.         else
  85.         {
  86.             TxtLen = strlen(TxtPtr+9);
  87.             SpcLen = ((5-((TxtLen)&3))&3);
  88.             strncat(TxtPtr+9,"   ",SpcLen);
  89.         }
  90.  
  91.         /* gewünschte Ausrichtung berechnen */
  92.         xPosPtr = (WORD*) TxtPtr;
  93.              if (xPosPtr[0] == (WORD) SMTPOS_C) xPosPtr[0] = (640-(TxtLen*8))/2
  94.         else if (xPosPtr[0] == (WORD) SMTPOS_L) xPosPtr[0] = 12;
  95.         else if (xPosPtr[0] == (WORD) SMTPOS_R) xPosPtr[0] = (640-(TxtLen*8))-12;
  96.     }
  97. }
  98.  
  99. /*
  100. ** ----------------------------------------
  101. ** Support-Funktionen für Device-Handhabung
  102. ** ----------------------------------------
  103. */
  104.  
  105. /*** rhosigma / GetIOReq()                        V2.118 ***
  106. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  107. * Diese Funktion belegt und initialisiert einen neuen IORequest, welcher dann
  108. * zur Kommunikation mit Devices verwendet werden kann.
  109. *  Da diese Routine universell einsetzbar sein soll, wird jedoch nur ein APTR
  110. * auf eine beliebige Struktur zurückgegeben, die man dann »casten« kann.
  111. *-----------------------------------------------------------------------------
  112. * Synopsis:        IOReq = GetIOReq (Size)
  113. *
  114. * Eingaben:        Size    --> (UWORD) Größe des benötigten IORequests in Byte.
  115. *
  116. * Ergebnis:        IOReq    --> (APTR) Zeiger auf den neuen IORequest oder NULL,
  117. *                                   wenn der Request nicht belegt werden konnte.
  118. *
  119. * Bemerkung:    Die Ursache für das Fehlschlagen dieser Funktion ist entweder
  120. *                Speichermangel, oder es war kein Signal-Bit für den Reply-Port
  121. *                des IORequests mehr frei.
  122. *
  123. * Siehe auch:    »CopyIOReq()«, »FreeIOReq()«
  124. *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
  125.  
  126. APTR GetIOReq(UWORD Size)
  127. {
  128.     APTR IOReq = NULL;
  129.  
  130.     /* versuche Reply-Port zu belegen */
  131.     struct MsgPort *Port = CreatePort(NULL,NULL);
  132.     if (Port)
  133.     {
  134.         /* versuche IORequest zu belegen */
  135.         IOReq = (APTR) CreateExtIO(Port,Size);
  136.         if (!IOReq)       DeletePort(Port);
  137.     }
  138.  
  139.     /* initialisierter IORequest */
  140.     return IOReq;
  141. }
  142.  
  143. /*** rhosigma / CopyIOReq()                        V2.118 ***
  144. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  145. * Diese Funktion legt eine Kopie von einem IORequest an, damit man z.B. für
  146. * Lese- und Schreibzugriffe einen seperaten Request zur Verfügung hat.
  147. *  Da diese Routine universell einsetzbar sein soll, wird jedoch nur ein APTR
  148. * auf eine beliebige Struktur zurückgegeben, die man dann »casten« kann.
  149. *-----------------------------------------------------------------------------
  150. * Synopsis:        CopyReq = CopyIOReq(OrigReq)
  151. *
  152. * Eingaben:        OrigReq    --> (APTR) Zeiger auf einen über »exec/OpenDevice()« be-
  153. *                                   reits vollständig initialisierten IORequest.
  154. *
  155. * Ergebnis:        CopyReq    --> (APTR) Zeiger auf den neuen IORequest oder NULL,
  156. *                                   wenn der Request nicht belegt werden konnte.
  157. *
  158. * Bemerkung:    Die Ursache für das Fehlschlagen dieser Funktion ist entweder
  159. *                Speichermangel, oder es war kein Signal-Bit für den Reply-Port
  160. *                des IORequests mehr frei.
  161. *                 Der mit dieser Funktion erstellte IORequest muß, wenn er nicht
  162. *                mehr benötigt wird, ebenfalls mit »FreeIOReq()« wieder freige-
  163. *                geben werden.
  164. *
  165. *   ACHTUNG:    Sie dürfen niemals einen kopierten IORequest bei einen Aufruf
  166. *   ¯¯¯¯¯¯¯¯    der Funktion »exec/CloseDevice()« verwenden. Benutzen Sie zu
  167. *                diesem Zwecke immer den originalen IORequest, mit dem Sie auch
  168. *                die Funktion »exec/OpenDevice()« aufgerufen haben.
  169. *
  170. * Siehe auch:    »GetIOReq()«, »FreeIOReq()«
  171. *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
  172.  
  173. APTR CopyIOReq(APTR OrigReq)
  174. {
  175.     /* APTR casten */
  176.     struct IORequest *OldReq = (struct IORequest*) OrigReq;
  177.  
  178.     /* neuen IORequest mit entsprechender Size anfordern */
  179.     APTR CopyReq = GetIOReq(OldReq -> io_Message.mn_Length);
  180.     if (CopyReq)
  181.     {
  182.         /* neuen APTR jetzt casten */
  183.         struct IORequest *NewReq = (struct IORequest*) CopyReq;
  184.  
  185.         /* alle wichtigen Einträge übertragen */
  186.         NewReq -> io_Message.mn_Node.ln_Type = OldReq -> io_Message.mn_Node.ln_Type;
  187.         NewReq -> io_Message.mn_Node.ln_Pri     = OldReq -> io_Message.mn_Node.ln_Pri;
  188.         NewReq -> io_Message.mn_Node.ln_Name = OldReq -> io_Message.mn_Node.ln_Name;
  189.         NewReq -> io_Message.mn_Length         = OldReq -> io_Message.mn_Length;
  190.         NewReq -> io_Device                     = OldReq -> io_Device;
  191.         NewReq -> io_Unit                     = OldReq -> io_Unit;
  192.     }
  193.  
  194.     // initialisierter neuer IORequest */
  195.     return CopyReq;
  196. }
  197.  
  198. /*** rhosigma / FreeIOReq()                        V2.118 ***
  199. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  200. * Diese Funktion gibt einen IORequest und alle damit verbundenen Resourcen
  201. * wieder an das System zurück.
  202. *-----------------------------------------------------------------------------
  203. * Synopsis:        VOID FreeIOReq (IOReq)
  204. *
  205. * Eingaben:        IOReq    --> (APTR) Zeiger auf den freizugebenden IORequest.
  206. *
  207. *   ACHTUNG:    Diese Funktion darf nur für IORequests aufgerufen werden, die
  208. *   ¯¯¯¯¯¯¯¯    entweder direkt mit der Funktion »GetIOReq()«, oder indirekt
  209. *                über die Funktion »CopyIOReq()« erstellt worden sind.
  210. *
  211. * Siehe auch:    »GetIOReq()«, »CopyIOReq()«
  212. *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
  213.  
  214. VOID FreeIOReq(APTR IOReq)
  215. {
  216.     /* APTR casten */
  217.     struct IORequest *Req = (struct IORequest*) IOReq;
  218.  
  219.     /* Wenn IORequest != NULL, dann erst Reply-Port und dann */
  220.     /* IORequest selbst freigeben                              */
  221.     if (Req)
  222.     {
  223.         struct MsgPort *Port = Req -> io_Message.mn_ReplyPort;
  224.         if (Port)               DeletePort(Port);
  225.         DeleteExtIO(Req);
  226.     }
  227. }
  228.  
  229. /*** rhosigma / DoCMD()                            V2.118 ***
  230. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  231. * Diese Funktion initialisiert den IORequest mit dem angegbenen Kommando
  232. * und sendet dieses dann im synchronen IO-Modus an das Device.
  233. *-----------------------------------------------------------------------------
  234. * Synopsis:        Error = DoCMD (IOReq, Comm)
  235. *
  236. * Eingaben:        IOReq    --> (APTR)    Zeiger auf den IORequest des anzusprechen-
  237. *                                    den Devices.
  238. *                Comm    --> (UWORD) Auszuführendes Device-Kommando.
  239. *
  240. * Ergebnis:        Error    --> (BYTE) Ist NULL, wenn alles in Ordnung, sonst eine
  241. *                                   Fehlernummer des angesprochenen Devices
  242. *                                   (s.a. Device-Includes).
  243. *
  244. * Siehe auch:    »SendCMD()«, »WaitCMD()«
  245. *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
  246.  
  247. BYTE DoCMD(APTR IOReq,UWORD Comm)
  248. {
  249.     /* APTR casten */
  250.     struct IORequest *Req = (struct IORequest*) IOReq;
  251.  
  252.     /* IORequest mit Device-Kommando laden und Request ans Device senden */
  253.     /* und Ergebnis des Aufrufs zurückgeben                                 */
  254.     Req -> io_Command = Comm;
  255.     return DoIO(Req);
  256. }
  257.  
  258. /*** rhosigma / SendCMD()                        V2.118 ***
  259. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  260. * Diese Funktion initialisiert den IORequest mit dem angegbenen Kommando
  261. * und sendet dieses dann im asynchronen IO-Modus an das Device.
  262. *-----------------------------------------------------------------------------
  263. * Synopsis:        VOID SendCMD (IOReq, Comm)
  264. *
  265. * Eingaben:        IOReq    --> (APTR)    Zeiger auf den IORequest des anzusprechen-
  266. *                                    den Devices.
  267. *                Comm    --> (UWORD) Auszuführendes Device-Kommando.
  268. *
  269. * Bemerkung:    Da diese Funktion nicht auf die Beendigung des IO-Vorgangs
  270. *                wartet, kann sie natürlich auch keine Auskunft über Erfolg oder
  271. *                Fehlschlag des selbigen geben. Sie sollten daher, wenn Sie mit
  272. *                den anderen Dingen, welche Sie asynchron nebenherlaufen lassen
  273. *                haben, fertig sind, die Funktion »WaitCMD()« aufrufen, welche
  274. *                sowohl die eventuelle Fehlernummer liefert, sowie die erforder-
  275. *                lichen Abschlußarbeiten erledigt.
  276. *
  277. * Siehe auch:    »DoCMD()«, »WaitCMD()«
  278. *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
  279.  
  280. VOID SendCMD(APTR IOReq,UWORD Comm)
  281. {
  282.     /* APTR casten */
  283.     struct IORequest *Req = (struct IORequest*) IOReq;
  284.  
  285.     /* IORequest mit Device-Kommando laden und ans Device senden */
  286.     Req -> io_Command = Comm;
  287.     SendIO(Req);
  288. }
  289.  
  290. /*** rhosigma / WaitCMD()                        V2.118 ***
  291. *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
  292. * Diese Funktion wartet auf die Beendigung eines zuvor mittels »SendCMD()« ge-
  293. * starteten asynchronen IO-Vorgangs.
  294. *-----------------------------------------------------------------------------
  295. * Synopsis:        Error = WaitCMD (IOReq)
  296. *
  297. * Eingaben:        IOReq    --> (APTR) Zeiger auf einen bereits an ein Device ge-
  298. *                                   sendeten IORequest.
  299. *
  300. * Ergebnis:        Error    --> (BYTE) Ist NULL, wenn alles in Ordnung, sonst eine
  301. *                                   Fehlernummer des angesprochenen Devices
  302. *                                   (s.a. Device-Includes).
  303. *
  304. * Bemerkung:    Mit einem »SendCMD()/WaitCMD()«-Paar erreichen Sie praktisch
  305. *                das geleiche, wie mit einem Aufruf von »DoCMD()«, nur mit dem
  306. *                Unterschied, daß Ihr Task bei letzteren in Wartestatus ver-
  307. *                setzt wird, und Sie bei ersterer Methode während der anfallen-
  308. *                den Wartezeit (z.B. wenn eine Disk geladen wird) anderen Auf-
  309. *                gaben nachgehen können (z.B. Berechnungen etc.). Sollte der
  310. *                IO-Vorgang bereits beendet sein, wenn Sie diese Funktion auf-
  311. *                rufen, dann kehrt sie unverzüglich mit entsprechenden Ergebnis
  312. *                zurück.
  313. *
  314. * Siehe auch:    »DoCMD()«, »SendCMD()«
  315. *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
  316.  
  317. BYTE WaitCMD(APTR IOReq)
  318. {
  319.     /* APTR casten */
  320.     struct IORequest *Req = (struct IORequest*) IOReq;
  321.  
  322.     /* Auf Beendigung des IO-Vorgangs warten und Fehler merken */
  323.     BYTE Err = WaitIO(Req);
  324.  
  325.     /* Eventuell noch gesetztes Signal-Bit löschen */
  326.     /* dazu zuerst Signal-Bit ermitteln               */
  327.     struct MsgPort *Port = Req -> io_Message.mn_ReplyPort;
  328.     ULONG  SigMask         = 1<<(Port -> mp_SigBit);
  329.  
  330.     /* Dann Signal-Task ermitteln und Bit löschen */
  331.     struct Task *Tcb    = (struct Task*) Port -> mp_SigTask;
  332.     Tcb -> tc_SigRecvd    = ((Tcb -> tc_SigRecvd)|SigMask)^SigMask;
  333.  
  334.     /* Funktion beenden und Fehler zurückgeben */
  335.     return Err;
  336. }
  337.  
  338.